package com.lora.service.resolver;

import com.google.common.base.Splitter;
import com.lora.common.ColumnParse;
import com.lora.dto.EquipmentDto;
import com.lora.entity.ElectricityMeter;
import com.lora.service.ElectricityMeterService;
import com.lora.service.NodeDataResolver;
import com.lora.web.BaseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Iterator;

@Slf4j
@Component("electricityMeterResolver")
public class ElectricityMeterResolver implements NodeDataResolver<ElectricityMeter> {

    @Resource
    private ElectricityMeterService electricityMeterService;

    @Override
    public EquipmentDto<ElectricityMeter> resolve(String equipmentNumber, String data) {
        data = BaseUtil.base64ToHex(data);
        EquipmentDto<ElectricityMeter> equipmentDto = new EquipmentDto<>();
        String modBusData = data.substring(6);
        String responseData = modBusData; // modBusData.substring(16); 如果不使用机房卫士则没有请求的数据
        String businessData = responseData.substring(6, responseData.length() - 4);
        Iterable<String> split = Splitter.fixedLength(4).split(businessData);
        Iterator<String> iterator = split.iterator();
        int index = 1;
        ElectricityMeter electricityMeter = new ElectricityMeter();
        electricityMeter.setEquipmentid(equipmentNumber);
        electricityMeter.setDatastring(data);
        Field[] declaredFields = electricityMeter.getClass().getDeclaredFields();
        while(iterator.hasNext()) {
            int finalFlag = index;
            index ++;
            String splitData = iterator.next();
            Field field = Arrays.asList(declaredFields).stream().filter(v -> {
                ColumnParse annotation = v.getAnnotation(ColumnParse.class);
                if (annotation != null) {
                    if (annotation.seq() == finalFlag) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }).findAny().orElse(null);
            if(field != null) {
                ColumnParse annotation = field.getAnnotation(ColumnParse.class);
                field.setAccessible(true);
                try {
                    field.set(electricityMeter, new BigDecimal(Integer.parseInt(splitData, 16)).multiply(new BigDecimal(annotation.ratio())));
                } catch (IllegalAccessException e) {
                    log.error("解析电量仪数据{}出错:{}", field.getName(), e);
                }
            }
        }


        electricityMeter.setAAvailablePower(electricityMeter.getAVoltage().multiply(electricityMeter.getACurrent()).multiply(electricityMeter.getAPowerFactor()));
        electricityMeter.setBAvailablePower(electricityMeter.getBVoltage().multiply(electricityMeter.getBCurrent()).multiply(electricityMeter.getBPowerFactor()));
        electricityMeter.setCAvailablePower(electricityMeter.getCVoltage().multiply(electricityMeter.getCCurrent()).multiply(electricityMeter.getCPowerFactor()));

        electricityMeter.setAUselessPower(electricityMeter.getAVoltage().multiply(electricityMeter.getACurrent()).
                multiply(new BigDecimal(Math.sin(electricityMeter.getAPowerFactor().doubleValue()))));
        electricityMeter.setBUselessPower(electricityMeter.getBVoltage().multiply(electricityMeter.getBCurrent()).
                multiply(new BigDecimal(Math.sin(electricityMeter.getBPowerFactor().doubleValue()))));
        electricityMeter.setCUselessPower(electricityMeter.getCVoltage().multiply(electricityMeter.getCCurrent()).
                multiply(new BigDecimal(Math.sin(electricityMeter.getCPowerFactor().doubleValue()))));

        equipmentDto.setEntity(electricityMeter);
        return equipmentDto;
    }

    @Override
    public ElectricityMeter save(ElectricityMeter equipment, boolean alarmFlag) {
        equipment.setAlarmFlag(alarmFlag);
        electricityMeterService.save(equipment);
        return equipment;
    }

    public static void main(String[] args) throws IllegalAccessException {
        String data =
                "04032301039c41001ebb8601033c5e2d5d1b5db5010600e9012f00780000007f0000028f0039002c00110018002000460393032300f613835ed4000065e600000000000000000000000046b0";
        String modbusData = data.substring(6);
        String responseData = modbusData.substring(16);
        String busiData = responseData.substring(6, responseData.length() - 4);
        Iterable<String> split = Splitter.fixedLength(4).split(busiData);
        Iterator<String> iterator = split.iterator();
        int index = 1;

        ElectricityMeter electricityMeter = new ElectricityMeter();
        Field[] declaredFields = electricityMeter.getClass().getDeclaredFields();
        while(iterator.hasNext()) {
            int finalIndex = index;
            index ++;
            String splitData = iterator.next();
            // System.out.println((index++) + ":" + splitData + ":" + Integer.parseInt(splitData, 16));
            Field field = Arrays.asList(declaredFields).stream().filter(v -> {
                ColumnParse annotation = v.getAnnotation(ColumnParse.class);
                if (annotation != null) {
                    if (annotation.seq() == finalIndex) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return false;
                }
            }).findAny().orElse(null);
            if(field != null) {
                ColumnParse annotation = field.getAnnotation(ColumnParse.class);
                System.out.println(field.getName() + ":" + new BigDecimal(Integer.parseInt(splitData, 16)).multiply
                        (new BigDecimal(annotation.ratio())).doubleValue());
                field.setAccessible(true);
                field.set(electricityMeter, new BigDecimal(Integer.parseInt(splitData, 16)).multiply(new BigDecimal(annotation.ratio())));
            }
        }
        System.out.println(electricityMeter.toString());
    }
}
